package com.epfly.promo.activity.impl;


import com.epfly.base.ex.PromoException;
import com.epfly.base.ex.PromoMessageEnum;
import com.epfly.base.id.SnowflakeIdService;
import com.epfly.base.util.DateUtil;
import com.epfly.base.vo.BaseResp;
import com.epfly.base.vo.PageResp;
import com.epfly.base.vo.RowsResp;
import com.epfly.iface.promo.activity.ActivityService;
import com.epfly.iface.promo.activity.enums.*;
import com.epfly.iface.promo.activity.vo.*;
import com.epfly.ifood.base.uims.model.enums.DelFlagStatusEnum;
import com.epfly.promo.activity.dao.*;
import com.epfly.promo.activity.entity.*;
import com.epfly.promo.activity.feign.DataRestaurantFeignService;
import com.epfly.promo.activity.impl.discount.ActivityDiscountFunction;
import com.epfly.promo.activity.impl.discount.ActivityWrapper;
import com.epfly.promo.activity.impl.discount.DiscountFun;
import com.epfly.promo.activity.impl.discount.predicate.ActivityDiscountPredicate;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.base.Splitter;
import com.ifood.model.merchants.param.MerchantOptions;
import com.ifood.model.merchants.param.request.MerchantQuery;
import com.ifood.model.merchants.param.response.MerchantInfo;
import com.ifood.model.merchants.param.response.StoreInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;


@Slf4j
@Service
public class ActivityServiceImpl implements ActivityService, InitializingBean {

    @Resource
    private ActivityMapper activityMapper;

    @Resource
    private ActivityFoodCategoryMapper activityFoodCategoryMapper;

    @Resource
    private ActivityFoodMapper activityFoodMapper;

    @Resource
    private ActivityBargainFoodMapper activityBargainFoodMapper;

    @Resource
    private ActivityObjectMapper activityObjectMapper;

    @Resource
    private ActivityStoreMapper activityStoreMapper;

    @Resource
    private ActivityRuleMapper activityRuleMapper;

    @Resource
    private ActivityDinnerBoundMapper activityDinnerBoundMapper;

    @Resource
    private ActivityDayBoundMapper activityDayBoundMapper;

    @Resource
    private ActivityActiveStoredMapper activityActiveStoredMapper;

    @Resource
    private SnowflakeIdService snowflakeIdService;

    @Resource
    private DataRestaurantFeignService dataRestaurantFeignService;

    @Resource
    private ActivityConfiguration activityConfiguration;

    @Resource
    private ActivitySupport activitySupport;


    public ActivityServiceImpl() {

    }

    @Override
    public GetDiscountAmountWithBoundResp getDiscountAmountWithBound(GetDiscountAmountWithBoundRequest request) {
        DiscountInVo in = new DiscountInVo();
        BeanUtils.copyProperties(request, in);
        DiscountFun discountFun = getDiscountAmount(in);

        GetDiscountAmountWithBoundResp resp = new GetDiscountAmountWithBoundResp();
        resp.setActivityId(discountFun.getActivityId());
        resp.setDiscountAmount(discountFun.getDiscountAmount());

        if (Objects.nonNull(discountFun.getActivityId())) {

            ActivityDayBoundEntity dayBoundEntity = activityDayBoundMapper.findByActivityIdAndIsActive(discountFun.getActivityId(), IsActiveEnum.YES.getKey());
            if (Objects.nonNull(dayBoundEntity)) {
                ActivityDayBoundVo dayBound = new ActivityDayBoundVo();
                dayBound.setAmountBound(dayBoundEntity.getAmountBound());
                dayBound.setCountBound(dayBoundEntity.getCountBound());
                dayBound.setIsActive(dayBoundEntity.getIsActive());
                resp.setDayBound(dayBound);
            }

            Byte dinnerType = dataRestaurantFeignService.getMealType(request.getMerchantId(), request.getStoreId(), request.getOrderTime()).byteValue();
            ActivityDinnerBoundEntity dinnerBoundEntity = activityDinnerBoundMapper.findByActivityIdAndDinnerTypeAndIsActive(discountFun.getActivityId(), dinnerType, IsActiveEnum.YES.getKey());
            if (Objects.nonNull(dinnerBoundEntity)) {
                ActivityDinnerBoundVo dinnerBound = new ActivityDinnerBoundVo();
                dinnerBound.setAmountBound(dayBoundEntity.getAmountBound());
                dinnerBound.setCountBound(dayBoundEntity.getCountBound());
                dinnerBound.setIsActive(dayBoundEntity.getIsActive());
                resp.setDinnerBound(dinnerBound);
            }
        }

        return resp;
    }

    /**
     * 供用户下单前实时计算优惠使用
     */
    @Override
    public GetDiscountAmountResp getDiscountAmount(GetDiscountAmountRequest request) {
        GetDiscountAmountResp resp = new GetDiscountAmountResp();

        DiscountInVo in = new DiscountInVo();
        BeanUtils.copyProperties(request, in);
        DiscountFun discountFun = getDiscountAmount(in);

        resp.setDiscountAmount(discountFun.getDiscountAmount());

        return resp;
    }

    /**
     * 计算订单最终参与的优惠活动 activityId
     * 拿到订单参与优惠活动的规则 ruleId
     * 计算订单拿到的最大优惠金额 discountAmount
     */
    public DiscountFun getDiscountAmount(DiscountInVo in) {

        // 查看"商户+档口"是否有"有效的"、"启用的"优惠活动, "" 表示不限制档口
        String merchantId = in.getMerchantId();
        String storeId = in.getStoreId();
        List<Long> activityIdList = activityActiveStoredMapper.findByMerchantIdAndStoreId(merchantId, storeId, StringUtils.EMPTY);
        log.info("hit activityIdList={}", activityIdList);
        if (CollectionUtils.isEmpty(activityIdList)) {
            return DiscountFun.builder().discountAmount(BigDecimal.ZERO).build();
        }

        List<ActivityEntity> entities = activityMapper.findByActivityIdList(activityIdList);

        long millisStartTime = System.currentTimeMillis();
        log.info("计算优惠开始时间:{}", DateUtil.getCurrentTime());
        Stream<ActivityWrapper> stream = entities.parallelStream().map(e -> {

            ActivityWrapper wrapper = new ActivityWrapper();
            wrapper.setActivityEntity(e);
            wrapper.setMerchantId(in.getMerchantId());
            wrapper.setStoreId(in.getStoreId());
            wrapper.setUserID(in.getUserID());
            wrapper.setPayAmount(in.getPayAmount());
            wrapper.setOrderTime(in.getOrderTime());
            wrapper.setOrderMethod(in.getOrderMethod());
            wrapper.setTakeMethod(in.getTakeMethod());
            wrapper.setFoodIdList(in.getFoodIdList());
            return wrapper;
        });

        // 设置所有断言
        for (Predicate<ActivityWrapper> predicate : this.predicates) {
            stream = stream.filter(e -> {
                boolean test = predicate.test(e);
                log.info("activityId={}, predicate={}, test={}", e.getActivityEntity().getId(), predicate, test);
                return test;
            });
        }

        // 计算最大优惠金额
        DiscountFun max = stream.map(activityWrapper -> {
                    ActivityEntity activityEntity = activityWrapper.getActivityEntity();
                    // 根据餐别取出优惠策略，计算出优惠
                    DiscountFun fun = discountMap.get(activityEntity.getDiscountType()).apply(activityWrapper);
                    log.info("activityId={}, discountAmount={}", fun.getActivityId(), fun.getDiscountAmount());
                    return fun;
                }).max(Comparator.comparing(DiscountFun::getDiscountAmount))
                .orElse(DiscountFun.builder().discountAmount(BigDecimal.ZERO).build());
        log.info("final activityId={}, maxDiscountAmount={}", max.getActivityId(), max.getDiscountAmount());
        long millisEndTime = System.currentTimeMillis();
        log.info("计算优惠结束时间:{}", DateUtil.getCurrentTime());
        log.info("计算优惠耗时:{}毫秒", millisEndTime - millisStartTime);

        return max;
    }

    @Override
    public RowsResp<StoreCountVo> storeCount(StoreCountRequest request) {

        // 查入参日期区间的活动
        List<String> activityIdList = getActivityIdList(request.getActivityStartTime(), request.getActivityEndTime(), request.getActivityId());
        if (CollectionUtils.isNotEmpty(activityIdList)) {
            List<StoreInfo> storeInfos = dataRestaurantFeignService.queryStoreByMerchantId(request.getMerchantId());
            if (CollectionUtils.isNotEmpty(storeInfos)) {
                List<String> storeIdList = storeInfos.stream().map(StoreInfo::getStoreId).collect(Collectors.toList());

                // 根据活动ID和档口ID，计算每个档口参与的活动次数
                return new RowsResp<>(getStoreCountList(activityIdList, storeIdList));
            }
        }
        return new RowsResp<>();
    }

    private List<StoreCountVo> getStoreCountList(List<String> activityIdList, List<String> scoreIdList) {
        List<ActivityStoreEntity> storeEntities = activityStoreMapper.findByActivityIdListAndStoreIdList(activityIdList, scoreIdList);
        Map<String, List<ActivityStoreEntity>> storeIdMap = storeEntities.stream().collect(Collectors.groupingBy(ActivityStoreEntity::getStoreId));

        List<StoreCountVo> storeCountList = new ArrayList<>(storeIdMap.size());
        storeIdMap.forEach((k, v) -> {
            StoreCountVo vo = new StoreCountVo();
            vo.setStoreId(k);
            vo.setCount(v.size());
            storeCountList.add(vo);
        });
        return storeCountList;
    }

    /**
     * 查某一时间区间的活动
     */
    private List<String> getActivityIdList(Long startTime, Long endTime, Long activityId) {

        ActivityEntity sEn = new ActivityEntity();
        sEn.setActivityStartTime(startTime);
        sEn.setActivityEndTime(endTime);
        sEn.setId(activityId);
        return activityMapper.findByInPeriod(sEn);
    }

    /**
     * 用于新增活动时判断每个档口涉及的活动数限制
     *
     * @param startTime   活动开始日期
     * @param endTime     活动结束日期
     * @param storeIdList 档口ID列表
     */
    private void storeCountValidation(Long startTime, Long endTime, List<String> storeIdList) {
        this.storeCountValidation(startTime, endTime, storeIdList, null);
    }

    /**
     * 用于修改活动时判断每个档口涉及的活动数限制
     *
     * @param startTime   活动开始日期
     * @param endTime     活动结束日期
     * @param storeIdList 档口ID列表
     * @param activityId  活动ID
     */
    private void storeCountValidation(Long startTime, Long endTime, List<String> storeIdList, Long activityId) {
        if (CollectionUtils.isEmpty(storeIdList)) {
            return;
        }
        // 查入参日期区间的活动
        List<String> activityIdList = getActivityIdList(startTime, endTime, activityId);
        if (activityIdList.size() < activityConfiguration.getMaxScoreCount()) {
            return;
        }
        List<ActivityStoreEntity> storeEntities = activityStoreMapper.findByActivityIdListAndStoreIdList(activityIdList, storeIdList);
        Map<String, List<ActivityStoreEntity>> storeIdMap = storeEntities.stream().collect(Collectors.groupingBy(ActivityStoreEntity::getStoreId));
        storeIdMap.forEach((storeId, v) -> {
            if (v.size() > activityConfiguration.getMaxScoreCount()) {

                String activityIds = v.stream().map(e -> String.valueOf(e.getActivityId())).collect(Collectors.joining(","));
                // ERR_100016("档口:%s，已经绑定%d个活动(%s)，达到最大限制")
                throw new PromoException(PromoMessageEnum.ERR_430016, storeId, String.valueOf(activityConfiguration.getMaxScoreCount()), activityIds);
            }
        });


    }

    @Override
    public ActivityDetailResp performActivityDetail(Long activityId) {
        if (Objects.isNull(activityId)) {
            // ERR_100012("活动ID不能为空")
            throw new PromoException(PromoMessageEnum.ERR_430012);
        }

        ActivityEntity sEn = new ActivityEntity();
        sEn.setId(activityId);
        ActivityEntity activityEntity = activityMapper.selectByPrimaryKey(sEn);
        if (Objects.isNull(activityEntity)) {
            // ERR_100013("活动不存在")
            throw new PromoException(PromoMessageEnum.ERR_430013);
        }

        ActivityDetailResp detail = new ActivityDetailResp();
        detail.setActivityId(activityEntity.getId());
        detail.setMerchantId(activityEntity.getMerchantId());

        MerchantOptions merchantOptions = new MerchantOptions();
        merchantOptions.setMerchantId(activityEntity.getMerchantId());
        MerchantInfo merchantInfo = dataRestaurantFeignService.queryByMerchantId(merchantOptions);
        detail.setMerchantName(merchantInfo.getMerchantName());
        detail.setActivityName(activityEntity.getActivityName());
        detail.setActivityType(activityEntity.getActivityType());
        detail.setActivityTypeEx(ActivityTypeEnum.getValue(activityEntity.getActivityType()));
        detail.setDiscountType(activityEntity.getDiscountType());
        detail.setDiscountTypeEx(DiscountTypeEnum.getValue(activityEntity.getDiscountType()));

        /*
          优惠方式==菜品分类折扣，需要传菜品分类ID
          优惠方式==菜品折扣，需要传菜品ID
          优惠方式==特价菜，需要传菜品ID、特价金额
         */
        if (activityEntity.getDiscountType().equals(DiscountTypeEnum.FOOD_CATEGORY_REBATE.getKey())) {
            List<ActivityFoodCategoryEntity> entities = activityFoodCategoryMapper.findByActivityId(activityId);
            List<ActivityRelationVo> relationList = entities.stream().map(e -> {
                ActivityRelationVo vo = new ActivityRelationVo();
                vo.setRelationId(e.getRelationId());
                return vo;
            }).collect(Collectors.toList());
            detail.setRelationList(relationList);
        }
        if (activityEntity.getDiscountType().equals(DiscountTypeEnum.FOOD_REBATE.getKey())) {
            List<ActivityFoodEntity> entities = activityFoodMapper.findByActivityId(activityId);
            List<ActivityRelationVo> relationList = entities.stream().map(e -> {
                ActivityRelationVo vo = new ActivityRelationVo();
                vo.setRelationId(e.getRelationId());
                return vo;
            }).collect(Collectors.toList());
            detail.setRelationList(relationList);
        }
        if (activityEntity.getDiscountType().equals(DiscountTypeEnum.FOOD_BARGAIN.getKey())) {
            List<ActivityBargainFoodEntity> entities = activityBargainFoodMapper.findByActivityId(activityId);
            List<ActivityRelationVo> relationList = entities.stream().map(e -> {
                ActivityRelationVo vo = new ActivityRelationVo();
                vo.setRelationId(e.getRelationId());
                vo.setBargainAmount(e.getBargainAmount());
                return vo;
            }).collect(Collectors.toList());
            detail.setRelationList(relationList);
        }

        detail.setActivityStartTime(activityEntity.getActivityStartTime());
        detail.setActivityEndTime(foreverTime2Zero(activityEntity.getActivityEndTime()));
        // 活动对象类型
        List<Byte> activityObjectType = Splitter.on(ActivityUtil.DELIMITER).omitEmptyStrings().splitToList(activityEntity.getActivityObjectType()).stream().map(Byte::parseByte).collect(Collectors.toList());
        detail.setActivityObjectType(activityObjectType);
        detail.setActivityObjectTypeEx(ActivityObjectTypeEnum.getValue(activityObjectType));
        // 部门/职务
        detail.setActivityObjectTypeCascade(activityEntity.getActivityObjectTypeCascade());
        detail.setActivityObjectTypeEx(ActivityObjectTypeCascadeEnum.getValue(activityEntity.getActivityObjectTypeCascade()));
        // 活动对象类型含有员工，级联选项为指定部门或指定职务，即非不限
        if (activityEntity.getActivityObjectType().contains(String.valueOf(ActivityObjectTypeEnum.EMPLOYEE.getKey()))
                && !activityEntity.getActivityObjectTypeCascade().equals(ActivityObjectTypeCascadeEnum.NO_LIMIT.getKey())) {
            List<ActivityObjectEntity> entities = activityObjectMapper.findByActivityId(activityId);
            List<String> relatedObjectIdList = entities.stream().map(ActivityObjectEntity::getRelatedObjectId).collect(Collectors.toList());
            detail.setObjectIdList(relatedObjectIdList);
        }
        // 活动档口
        detail.setStoreStyle(activityEntity.getStoreStyle());
        detail.setStoreStyleEx(StoreStyleEnum.getValue(activityEntity.getStoreStyle()));
        // 活动档口为指定档口
        if (activityEntity.getStoreStyle().equals(StoreStyleEnum.ASSIGN.getKey())) {
            List<ActivityStoreEntity> entities = activityStoreMapper.findByActivityId(activityId);
            detail.setStoreIdList(entities.stream().map(ActivityStoreEntity::getStoreId).collect(Collectors.toList()));
        }
        // 适用星期
        List<Byte> effectiveDays = Splitter.on(ActivityUtil.DELIMITER).omitEmptyStrings().splitToList(activityEntity.getEffectiveDays()).stream().map(Byte::parseByte).collect(Collectors.toList());
        detail.setEffectiveDays(effectiveDays);
        detail.setEffectiveDaysEx(EffectiveDaysEnum.getValue(effectiveDays));
        // 活动节假日
        detail.setIsSuiteHoliday(activityEntity.getIsSuiteHoliday());
        detail.setIsSuiteHolidayEx(IsSuiteHolidayEnum.getValue(activityEntity.getIsSuiteHoliday()));
        // 下单方式
        List<Byte> effectiveOrderMethods = Splitter.on(ActivityUtil.DELIMITER).omitEmptyStrings().splitToList(activityEntity.getEffectiveOrderMethods()).stream().map(Byte::parseByte).collect(Collectors.toList());
        detail.setEffectiveOrderMethods(effectiveOrderMethods);
        detail.setEffectiveOrderMethodsEx(EffectiveOrderMethodsEnum.getValue(effectiveOrderMethods));

        // 取餐方式
        List<Byte> effectiveTakeMethods = Splitter.on(ActivityUtil.DELIMITER).omitEmptyStrings().splitToList(activityEntity.getEffectiveTakeMethods()).stream().map(Byte::parseByte).collect(Collectors.toList());
        detail.setEffectiveTakeMethods(effectiveTakeMethods);
        detail.setEffectiveTakeMethodsEx(EffectiveTakeMethodsEnum.getValue(effectiveTakeMethods));
        detail.setRemark(activityEntity.getRemark());

        // 活动规则、活动规则内容
        List<ActivityRuleEntity> ruleEntities = activityRuleMapper.findByActivityId(activityId);
        List<ActivityRuleVo> ruleList = ruleEntities.stream().map(ruleEntity -> {
            ActivityRuleVo ruleVo = new ActivityRuleVo();
            ruleVo.setDinnerType(ruleEntity.getDinnerType());
            ruleVo.setDinnerTypeEx(ActivityRuleDinnerTypeEnum.getValue(ruleEntity.getDinnerType()));
            ruleVo.setRuleContent(ruleEntity.getRuleContent());
            return ruleVo;
        }).collect(Collectors.toList());
        detail.setRuleList(ruleList);

        // 餐别活动限额限次
        List<ActivityDinnerBoundEntity> dinnerBoundEntities = activityDinnerBoundMapper.findByActivityId(activityId);
        List<ActivityDinnerBoundVo> boundList = dinnerBoundEntities.stream().map(e -> {
            ActivityDinnerBoundVo vo = new ActivityDinnerBoundVo();
            vo.setDinnerType(e.getDinnerType());
            vo.setDinnerTypeEx(ActivityRuleDinnerTypeEnum.getValue(e.getDinnerType()));
            vo.setAmountBound(e.getAmountBound());
            vo.setCountBound(e.getCountBound());
            vo.setIsActive(e.getIsActive());
            vo.setIsActiveEx(IsActiveEnum.getValue(e.getIsActive()));
            return vo;
        }).collect(Collectors.toList());
        detail.setDinnerBoundList(boundList);

        // 日活动限额限次
        ActivityDayBoundEntity dayBoundEntity = activityDayBoundMapper.findByActivityId(activityId);
        ActivityDayBoundVo dayBound = new ActivityDayBoundVo();
        dayBound.setAmountBound(dayBoundEntity.getAmountBound());
        dayBound.setCountBound(dayBoundEntity.getCountBound());
        dayBound.setIsActive(dayBoundEntity.getIsActive());
        dayBound.setIsActiveEx(IsActiveEnum.getValue(dayBoundEntity.getIsActive()));
        detail.setDayBound(dayBound);

        return detail;
    }

    @Transactional
    @Override
    public BaseResp performActivityUpdate(ActivityAddAndUpdateRequest activityRequest) {
        Long activityId = activityRequest.getActivityId();

        ActivityEntity sEn = new ActivityEntity();
        sEn.setId(activityId);
        ActivityEntity activityEntity = activityMapper.selectByPrimaryKey(sEn);
        if (Objects.isNull(activityEntity)) {
            // ERR_100011("活动不存在")
            throw new PromoException(PromoMessageEnum.ERR_430011);
        }

        if (!activityEntity.getStatus().equals(ActivityStatusEnum.WAIT.getKey())) {
            // ERR_100017("非待生效不能修改")
            throw new PromoException(PromoMessageEnum.ERR_430017);
        }

        // 请求校验
        requestValidation(activityRequest);

        storeCountValidation(activityRequest.getActivityStartTime(), activityRequest.getActivityEndTime(), activityRequest.getStoreIdList(), activityId);

        // 修改前，优惠方式==菜品分类折扣或优惠方式==菜品折扣或优惠方式==特价菜，清理关联的菜品或菜品分类或特价菜
        if (activityEntity.getDiscountType().equals(DiscountTypeEnum.FOOD_CATEGORY_REBATE.getKey())) {
            activityFoodCategoryMapper.deleteByActivityId(activityId);
        }
        if (activityEntity.getDiscountType().equals(DiscountTypeEnum.FOOD_REBATE.getKey())) {
            activityFoodMapper.deleteByActivityId(activityId);
        }
        if (activityEntity.getDiscountType().equals(DiscountTypeEnum.FOOD_BARGAIN.getKey())) {
            activityBargainFoodMapper.deleteByActivityId(activityId);
        }

        // 修改前，活动对象类型含有员工，级联选项为指定部门或指定职务，即非不限，清理关联的部门或职务
        if (activityEntity.getActivityObjectType().contains(String.valueOf(ActivityObjectTypeEnum.EMPLOYEE.getKey()))
                && !activityEntity.getActivityObjectTypeCascade().equals(ActivityObjectTypeCascadeEnum.NO_LIMIT.getKey())) {
            activityObjectMapper.deleteByActivityId(activityId);
        }

        // 修改前，活动档口为指定档口，清理关联的档口
        if (activityEntity.getStoreStyle().equals(StoreStyleEnum.ASSIGN.getKey())) {
            activityStoreMapper.deleteByActivityId(activityId);
        }

        // 修改前，活动规则清理、活动规则内容清理、活动规则限额清理
        activityRuleMapper.deleteByActivityId(activityId);
        activityDinnerBoundMapper.deleteByActivityId(activityId);
        activityDayBoundMapper.deleteByActivityId(activityId);

        // 因为"生效中"不允许修改，此场景忽略
//        // 修改前，"活动状态"等于"生效中"，当前活动"启用状态"为"启用"，清理处于活跃中的档口
//        if (activityEntity.getStatus().equals(ActivityStatusEnum.ACTIVE.getKey())
//                && activityEntity.getIsActive().equals(IsActiveEnum.YES.getKey())) {
//            activityActiveStoredMapper.deleteByActivityId(activityId);
//        }

        // 更新活动对象
        activityEntity.setId(activityRequest.getActivityId());
        cpRequest2En(activityRequest, activityEntity);
        activityMapper.updateByPrimaryKey(activityEntity);

        // 修改后，"活动状态"等于"生效中"，当前活动"启用状态"为"启用"，新增活跃档口
        if (activityEntity.getStatus().equals(ActivityStatusEnum.ACTIVE.getKey())
                && activityEntity.getIsActive().equals(IsActiveEnum.YES.getKey())) {
            if (CollectionUtils.isNotEmpty(activityRequest.getStoreIdList())) { // 指定挡口
                List<Long> ids = snowflakeIdService.nextIds(activityRequest.getStoreIdList().size());
                List<ActivityActiveStoreEntity> storeEntities = new ArrayList<>(activityRequest.getStoreIdList().size());
                for (int i = 0; i < activityRequest.getStoreIdList().size(); i++) {
                    ActivityActiveStoreEntity activeStoreEntity = new ActivityActiveStoreEntity();
                    activeStoreEntity.setId(ids.get(i));
                    activeStoreEntity.setMerchantId(activityRequest.getMerchantId());
                    activeStoreEntity.setActivityId(activityId);
                    activeStoreEntity.setStoreId(activityRequest.getStoreIdList().get(i));
                    activeStoreEntity.setUpdateTime(LocalDateTime.now());
                    activeStoreEntity.setCreateTime(LocalDateTime.now());
                    storeEntities.add(activeStoreEntity);
                }
                activityActiveStoredMapper.insertList(storeEntities);
            } else { // 不限
                activityActiveStoredMapper.insert(activitySupport.getUnLimitActiveStoreEn(activityRequest.getMerchantId(), activityId));
            }
        }

        relationObjects(activityRequest, activityId);

        return BaseResp.OK;
    }



    private void cpRequest2En(ActivityAddAndUpdateRequest activityRequest, ActivityEntity activityEntity) {
        activityEntity.setMerchantId(activityRequest.getMerchantId());
        activityEntity.setActivityName(activityRequest.getActivityName());
        activityEntity.setActivityType(activityRequest.getActivityType());
        activityEntity.setDiscountType(activityRequest.getDiscountType());

        activityEntity.setActivityStartTime((activityRequest.getActivityStartTime()));

        activityEntity.setActivityEndTime(zero2ForeverTime(activityRequest.getActivityEndTime()));
        activityEntity.setActivityObjectType(ActivityUtil.join(activityRequest.getActivityObjectTypeList()));
        activityEntity.setActivityObjectTypeCascade(activityRequest.getActivityObjectTypeCascade());
        activityEntity.setStoreStyle(activityRequest.getStoreStyle());
        activityEntity.setEffectiveDays(ActivityUtil.join(activityRequest.getEffectiveDays()));
        activityEntity.setIsSuiteHoliday(activityRequest.getIsSuiteHoliday());
        activityEntity.setEffectiveOrderMethods(ActivityUtil.join(activityRequest.getEffectiveOrderMethods()));
        activityEntity.setEffectiveTakeMethods(ActivityUtil.join(activityRequest.getEffectiveTakeMethods()));
        activityEntity.setRemark(activityRequest.getRemark());

        ActivityStatusEnum statusEnum = getStatus(activityRequest);
        activityEntity.setStatus(statusEnum.getKey());

        activityEntity.setCreateBy(activityRequest.getCreateBy());
    }


    private void relationObjects(ActivityAddAndUpdateRequest activityRequest, Long activityId) {
        if (CollectionUtils.isNotEmpty(activityRequest.getRelationList())) {
            List<Long> ids = snowflakeIdService.nextIds(activityRequest.getRelationList().size());
            // 优惠方式==菜品分类折扣，持久化菜品分类ID
            if (activityRequest.getDiscountType().equals(DiscountTypeEnum.FOOD_CATEGORY_REBATE.getKey())) {
                List<ActivityFoodCategoryEntity> entities = new ArrayList<>(activityRequest.getRelationList().size());
                for (int i = 0; i < activityRequest.getRelationList().size(); i++) {
                    ActivityFoodCategoryEntity foodCategoryEntity = new ActivityFoodCategoryEntity();
                    foodCategoryEntity.setId(ids.get(i));
                    foodCategoryEntity.setActivityId(activityId);
                    foodCategoryEntity.setRelationId(activityRequest.getRelationList().get(i).getRelationId());
                    foodCategoryEntity.setDelFlag(DelFlagStatusEnum.USE.getCode().byteValue());
                    foodCategoryEntity.setUpdateTime(LocalDateTime.now());
                    foodCategoryEntity.setCreateTime(LocalDateTime.now());
                    entities.add(foodCategoryEntity);
                }
                activityFoodCategoryMapper.insertList(entities);
            }

            // 优惠方式==菜品折扣，持久化菜品ID
            if (activityRequest.getDiscountType().equals(DiscountTypeEnum.FOOD_REBATE.getKey())) {
                List<ActivityFoodEntity> entities = new ArrayList<>(activityRequest.getRelationList().size());
                for (int i = 0; i < activityRequest.getRelationList().size(); i++) {
                    ActivityFoodEntity foodEntity = new ActivityFoodEntity();
                    foodEntity.setId(ids.get(i));
                    foodEntity.setActivityId(activityId);
                    foodEntity.setRelationId(activityRequest.getRelationList().get(i).getRelationId());
                    foodEntity.setDelFlag(DelFlagStatusEnum.USE.getCode().byteValue());
                    foodEntity.setUpdateTime(LocalDateTime.now());
                    foodEntity.setCreateTime(LocalDateTime.now());
                    entities.add(foodEntity);
                }
                activityFoodMapper.insertList(entities);
            }

            // 优惠方式==特价菜，需要传菜品ID
            if (activityRequest.getDiscountType().equals(DiscountTypeEnum.FOOD_BARGAIN.getKey())) {
                List<ActivityBargainFoodEntity> entities = new ArrayList<>(activityRequest.getRelationList().size());
                for (int i = 0; i < activityRequest.getRelationList().size(); i++) {
                    ActivityBargainFoodEntity bargainFoodEntity = new ActivityBargainFoodEntity();
                    bargainFoodEntity.setId(ids.get(i));
                    bargainFoodEntity.setActivityId(activityId);
                    bargainFoodEntity.setRelationId(activityRequest.getRelationList().get(i).getRelationId());
                    bargainFoodEntity.setBargainAmount(activityRequest.getRelationList().get(i).getBargainAmount());
                    bargainFoodEntity.setDelFlag(DelFlagStatusEnum.USE.getCode().byteValue());
                    bargainFoodEntity.setUpdateTime(LocalDateTime.now());
                    bargainFoodEntity.setCreateTime(LocalDateTime.now());
                    entities.add(bargainFoodEntity);
                }
                activityBargainFoodMapper.insertList(entities);
            }
        }

        // 当活动对象类型为员工时，级联选项为指定部门或指定职务时，持久化活动对象
        if (CollectionUtils.isNotEmpty(activityRequest.getObjectIdList())) {
            List<Long> ids = snowflakeIdService.nextIds(activityRequest.getObjectIdList().size());
            List<ActivityObjectEntity> objectEntities = new ArrayList<>(activityRequest.getObjectIdList().size());
            for (int i = 0; i < activityRequest.getObjectIdList().size(); i++) {
                ActivityObjectEntity objectEntity = new ActivityObjectEntity();
                objectEntity.setId(ids.get(i));
                objectEntity.setActivityId(activityId);
                objectEntity.setActivityObjectTypeCascade(activityRequest.getActivityObjectTypeCascade());
                objectEntity.setRelatedObjectId(activityRequest.getObjectIdList().get(i));
                objectEntity.setDelFlag(DelFlagStatusEnum.USE.getCode().byteValue());
                objectEntity.setUpdateTime(LocalDateTime.now());
                objectEntity.setCreateTime(LocalDateTime.now());
                objectEntities.add(objectEntity);
            }
            activityObjectMapper.insertList(objectEntities);
        }

        // 当活动档口为指定档口时，持久化档口对象
        if (CollectionUtils.isNotEmpty(activityRequest.getStoreIdList())) {
            List<Long> ids = snowflakeIdService.nextIds(activityRequest.getStoreIdList().size());
            List<ActivityStoreEntity> storeEntities = new ArrayList<>(activityRequest.getStoreIdList().size());
            for (int i = 0; i < activityRequest.getObjectIdList().size(); i++) {
                ActivityStoreEntity storeEntity = new ActivityStoreEntity();
                storeEntity.setId(ids.get(i));
                storeEntity.setActivityId(activityId);
                storeEntity.setStoreId(activityRequest.getStoreIdList().get(i));
                storeEntity.setDelFlag(DelFlagStatusEnum.USE.getCode().byteValue());
                storeEntity.setUpdateTime(LocalDateTime.now());
                storeEntity.setCreateTime(LocalDateTime.now());
                storeEntities.add(storeEntity);
            }
            activityStoreMapper.insertList(storeEntities);
        }

        // 活动规则、活动规则内容持久化
        List<Long> ruleIds = snowflakeIdService.nextIds(activityRequest.getRuleList().size());
        final List<ActivityRuleEntity> ruleEntities = new ArrayList<>(activityRequest.getRuleList().size());
        for (int i = 0; i < activityRequest.getRuleList().size(); i++) {
            ActivityRuleVo rule = activityRequest.getRuleList().get(i);
            ActivityRuleEntity ruleEntity = new ActivityRuleEntity();
            Long ruleId = ruleIds.get(i);
            ruleEntity.setId(ruleId);
            ruleEntity.setActivityId(activityId);
            ruleEntity.setDinnerType(rule.getDinnerType());
            ruleEntity.setRuleContent(rule.getRuleContent());
            ruleEntity.setDelFlag(DelFlagStatusEnum.USE.getCode().byteValue());
            ruleEntity.setUpdateTime(LocalDateTime.now());
            ruleEntity.setCreateTime(LocalDateTime.now());
            ruleEntities.add(ruleEntity);
        }
        activityRuleMapper.insertList(ruleEntities);


        // 餐别活动限额限次
        if (CollectionUtils.isNotEmpty(activityRequest.getDinnerBoundList())) {
            List<ActivityDinnerBoundEntity> dinnerBoundEntities = new ArrayList<>(activityRequest.getDinnerBoundList().size());
            List<Long> ids = snowflakeIdService.nextIds(activityRequest.getDinnerBoundList().size());
            for (int i = 0; i < activityRequest.getDinnerBoundList().size(); i++) {
                ActivityDinnerBoundVo bound = activityRequest.getDinnerBoundList().get(i);
                ActivityDinnerBoundEntity dinnerBoundEntity = new ActivityDinnerBoundEntity();
                dinnerBoundEntity.setId(ids.get(i));
                dinnerBoundEntity.setActivityId(activityId);
                dinnerBoundEntity.setDinnerType(bound.getDinnerType());
                dinnerBoundEntity.setAmountBound(bound.getAmountBound());
                dinnerBoundEntity.setCountBound(bound.getCountBound());
                dinnerBoundEntity.setIsActive(bound.getIsActive());
                dinnerBoundEntity.setDelFlag(DelFlagStatusEnum.USE.getCode().byteValue());
                dinnerBoundEntity.setUpdateTime(LocalDateTime.now());
                dinnerBoundEntity.setCreateTime(LocalDateTime.now());
                dinnerBoundEntities.add(dinnerBoundEntity);
            }
            activityDinnerBoundMapper.insertList(dinnerBoundEntities);
        }

        // 日活动限额限次
        if (Objects.nonNull(activityRequest.getDayBound())) {
            ActivityDayBoundVo bound = activityRequest.getDayBound();
            Long id = snowflakeIdService.nextId();
            ActivityDayBoundEntity entity = new ActivityDayBoundEntity();
            entity.setId(id);
            entity.setActivityId(activityId);
            entity.setAmountBound(bound.getAmountBound());
            entity.setCountBound(bound.getCountBound());
            entity.setIsActive(bound.getIsActive());
            activityDayBoundMapper.insertSelective(entity);
        }
    }

    @Transactional
    @Override
    public BaseResp performActivityTerminated(ActivityTerminatedRequest request) {
        Long activityId = request.getActivityId();
        ActivityEntity sEn = new ActivityEntity();
        sEn.setId(activityId);
        ActivityEntity activityEntity = activityMapper.selectByPrimaryKey(sEn);
        if (Objects.isNull(activityEntity)) {
            // ERR_100015("活动不存在"),
            throw new PromoException(PromoMessageEnum.ERR_430015);
        }

        // 已终止 --> 已终止
        if (activityEntity.getStatus().equals(ActivityStatusEnum.FINAL.getKey())) {
            // do nothing
            return BaseResp.OK;
        }

        // 待生效 --> 已终止，直接更新活动状态、活动结束时间


        // 生效中 --> 已终止，并且状态为启用，清理处于活跃中的档口，再更新活动状态、活动结束时间
        if (activityEntity.getStatus().equals(ActivityStatusEnum.ACTIVE.getKey())
                && activityEntity.getIsActive().equals(IsActiveEnum.YES.getKey())) {
            activityActiveStoredMapper.deleteByActivityId(activityId);
        }

        // 活动手工终结时，更新活动状态为已终结，同时更新活动结束时间
        activityMapper.terminateActivity(activityId, ActivityStatusEnum.FINAL.getKey(), DateUtil.getCurrentTime());

        return BaseResp.OK;
    }

    @Transactional
    @Override
    public BaseResp alterActivityIsActive(AlterActivityIsActiveRequest request) {
        final Long activityId = request.getActivityId();
        ActivityEntity sEn = new ActivityEntity();
        sEn.setId(activityId);
        ActivityEntity activityEntity = activityMapper.selectByPrimaryKey(sEn);
        if (Objects.isNull(activityEntity)) {
            // ERR_100009("活动不存在")
            throw new PromoException(PromoMessageEnum.ERR_430009);
        }

        /*
          活动状态为"生效中"，要考虑新增或清理处于活跃中的档口，再更新启用状态
          启用变为停用，清理处于活跃中的档口
          停用变为启用，新增处于活跃中的档口
          活动状态为"待生效"或"已终止"的情况下，只须更新启用状态
         */
        if (activityEntity.getStatus().equals(ActivityStatusEnum.ACTIVE.getKey())) {
            // 启用变为停用
            if (activityEntity.getIsActive().equals(IsActiveEnum.YES.getKey())) {
                activityActiveStoredMapper.deleteByActivityId(activityId);
            }

            // 停用变为启用
            if (activityEntity.getIsActive().equals(IsActiveEnum.NO.getKey())) {
                if (activityEntity.getStoreStyle().equals(StoreStyleEnum.UN_LIMIT.getKey())) { // 档口类型==不限
                    activityActiveStoredMapper.insert(activitySupport.getUnLimitActiveStoreEn(activityEntity.getMerchantId(), activityId));
                } else { // 档口类型==指定档口
                    List<ActivityStoreEntity> storeEntities = activityStoreMapper.findByActivityId(activityId);
                    List<Long> ids = snowflakeIdService.nextIds(storeEntities.size());
                    List<ActivityActiveStoreEntity> activeStoreEntities = new ArrayList<>(storeEntities.size());

                    for (int i = 0; i < storeEntities.size(); i++) {
                        ActivityStoreEntity storeEntity = storeEntities.get(i);
                        ActivityActiveStoreEntity activeStoreEntity = new ActivityActiveStoreEntity();
                        activeStoreEntity.setId(ids.get(i));
                        activeStoreEntity.setMerchantId(activityEntity.getMerchantId());
                        activeStoreEntity.setActivityId(activityId);
                        activeStoreEntity.setStoreId(storeEntity.getStoreId());
                        activeStoreEntity.setUpdateTime(LocalDateTime.now());
                        activeStoreEntity.setCreateTime(LocalDateTime.now());
                        activeStoreEntities.add(activeStoreEntity);
                    }
                    activityActiveStoredMapper.insertList(activeStoreEntities);
                }
            }
        }
        // 启用变停用，停用变启用
        activityMapper.modifyActivityIsActive(activityId, activityEntity.equals(IsActiveEnum.YES.getKey()) ? IsActiveEnum.NO.getKey() : IsActiveEnum.YES.getKey());

        return BaseResp.OK;
    }

    @Override
    public PageResp<ActivityListVo> performActivityList(ActivityListRequest activityListRequest) {

        Example example = Example.builder(ActivityEntity.class).build();
        example.setOrderByClause("id desc");
        Example.Criteria criteria = example.createCriteria();

        if (StringUtils.isNotEmpty(activityListRequest.getMerchantId())) {
            criteria.andEqualTo("merchantId", activityListRequest.getMerchantId());
        }
        if (StringUtils.isNotEmpty(activityListRequest.getActivityName())) {
            criteria.andLike("activityName", '%' + activityListRequest.getActivityName() + '%');
        }
        // 活动开始日期转为活动开始时间查询
        if (Objects.nonNull(activityListRequest.getActivityStartDate())) {
            criteria.andGreaterThanOrEqualTo("activityStartTime", date2StartTime(activityListRequest.getActivityStartDate()));
        }
        // 活动结束日期转为活动结束时间查询
        if (Objects.nonNull(activityListRequest.getActivityEndDate())) {
            criteria.andLessThanOrEqualTo("activityEndTime", date2EndTime(activityListRequest.getActivityEndDate()));
        }
        if (Objects.nonNull(activityListRequest.getActivityType())) {
            criteria.andEqualTo("activityType", activityListRequest.getActivityType());
        }
        if (Objects.nonNull(activityListRequest.getStatus())) {
            criteria.andEqualTo("status", activityListRequest.getStatus());
        }
        if (Objects.nonNull(activityListRequest.getIsActive())) {
            criteria.andEqualTo("isActive", activityListRequest.getIsActive());
        }

        try (Page<ActivityEntity> pages = PageHelper.startPage(activityListRequest.getPageNum(), activityListRequest.getPageSize())) {
            List<ActivityEntity> activityEntities = activityMapper.selectByExample(example);
            List<ActivityListVo> activities = new ArrayList<>(activityEntities.size());
            if (CollectionUtils.isNotEmpty(activityEntities)) {
                MerchantQuery merchantQuery = new MerchantQuery();
                Set<String> merchantIds = activityEntities.stream().map(ActivityEntity::getMerchantId).collect(Collectors.toSet());
                merchantQuery.setMerchantIds(merchantIds);
                Map<String, String> merchantMap = dataRestaurantFeignService.queryByMerchantIds(merchantQuery).stream().collect(Collectors.toMap(MerchantInfo::getMerchantId, MerchantInfo::getMerchantName));

                for (ActivityEntity activityEntity : activityEntities) {
                    ActivityListVo vo = new ActivityListVo();
                    vo.setActivityId(activityEntity.getId());
                    vo.setMerchantName(merchantMap.get(activityEntity.getMerchantId()));
                    vo.setActivityName(activityEntity.getActivityName());
                    vo.setActivityType(activityEntity.getActivityType());
                    vo.setActivityStartTime(activityEntity.getActivityStartTime());
                    vo.setActivityEndTime(foreverTime2Zero(activityEntity.getActivityEndTime()));
                    vo.setStatus(activityEntity.getStatus());
                    vo.setIsActive(activityEntity.getIsActive());
                    vo.setUpdateTime(activityEntity.getUpdateTime());
                    activities.add(vo);
                }
            }
            return new PageResp<>(pages.getPageNum(), pages.getPageSize(), pages.getTotal(), pages.getPages(), activities);
        }
    }

    @Transactional
    @Override
    public ActivityAddAndUpdateResp performActivityAdd(ActivityAddAndUpdateRequest activityAddRequest) {

        // 请求校验
        requestValidation(activityAddRequest);

        // 档口涉及的活动数校验
        storeCountValidation(activityAddRequest.getActivityStartTime(), activityAddRequest.getActivityEndTime(), activityAddRequest.getStoreIdList());

        // 持久化活动对象
        ActivityEntity activityEntity = new ActivityEntity();
        cpRequest2En(activityAddRequest, activityEntity);
        activityMapper.insertSelective(activityEntity);

        final Long activityId = activityEntity.getId();

        relationObjects(activityAddRequest, activityId);

        ActivityAddAndUpdateResp resp = new ActivityAddAndUpdateResp();
        resp.setActivityId(activityId);
        return resp;
    }

    /**
     * date == 0，表示永久，直接转为 20991024
     */
    static final Long foreverTime = 2099_10_24_23_59_59L;

    /**
     * 用于活动列表查询条件
     */
    private Long date2StartTime(Integer date) {
        return Long.valueOf(date + "000000");
    }

    /**
     * 用于活动列表查询条件
     */
    private Long date2EndTime(Integer date) {
        if (date == 0) {
            return foreverTime;
        }
        return Long.valueOf(date + "235959");
    }

    /**
     * 永久时间转为零
     * 用于活动列表、明细查询结果
     */
    private Long foreverTime2Zero(Long time) {
        if (time.equals(foreverTime)) {
            return 0L;
        }
        return time;
    }

    /**
     * 零转永久时间
     * 用于优惠活动新增、修改时
     */
    private Long zero2ForeverTime(Long time) {
        if (time.equals(0L)) {
            return foreverTime;
        }
        return time;
    }

    /**
     * 场景一：
     * 活动开始日期 ---  当前日期 --- 活动结束日期
     * 当前日期大于等于活动开始时间，并且小于等于活动结束日期，状态为"生效中" {@link ActivityStatusEnum#ACTIVE}
     * <p>
     * 场景二：
     * 活动开始日期 --- 活动结束日期 --- 当前日期
     * 当前日期大于活动结束日期，状态为"已终止" {@link ActivityStatusEnum#FINAL}
     * <p>
     * 场景三：
     * 当前日期 -- 活动开始日期 --- 活动结束日期
     * 当前日期小于活动开始日期，状态为"待生效" {@link ActivityStatusEnum#WAIT}
     */
    private ActivityStatusEnum getStatus(ActivityAddAndUpdateRequest activityAddRequest) {
        long currentTime = DateUtil.getCurrentTime();
        long activityStartTime = activityAddRequest.getActivityStartTime();
        long activityEndTime = activityAddRequest.getActivityEndTime();

        if (currentTime >= activityStartTime && currentTime <= activityEndTime) {
            return ActivityStatusEnum.ACTIVE;
        }

        if (currentTime > activityEndTime) {
            return ActivityStatusEnum.FINAL;
        }
        // 场景三作为默认值返回
        return ActivityStatusEnum.WAIT;
    }

    private void requestValidation(ActivityAddAndUpdateRequest activityAddRequest) {

        /*
          优惠方式==菜品分类折扣，需要传菜品分类ID
          优惠方式==菜品折扣，需要传菜品ID
          优惠方式==特价菜，需要传菜品ID
         */
        if (activityAddRequest.getDiscountType().equals(DiscountTypeEnum.FOOD_CATEGORY_REBATE.getKey())) {
            if (CollectionUtils.isEmpty(activityAddRequest.getRelationList())) {
                // ERR_100001("优惠方式为菜品分类折扣，菜品分类不能为空")
                throw new PromoException(PromoMessageEnum.ERR_430001);
            }
        }
        if (activityAddRequest.getDiscountType().equals(DiscountTypeEnum.FOOD_REBATE.getKey())) {
            if (CollectionUtils.isEmpty(activityAddRequest.getRelationList())) {
                // ERR_100002("优惠方式为菜品折扣，菜品ID不能为空")
                throw new PromoException(PromoMessageEnum.ERR_430002);
            }
        }
        if (activityAddRequest.getDiscountType().equals(DiscountTypeEnum.FOOD_BARGAIN.getKey())) {
            if (CollectionUtils.isEmpty(activityAddRequest.getRelationList())) {
                // ERR_100003("优惠方式为特价菜，菜品ID不能为空")
                throw new PromoException(PromoMessageEnum.ERR_430003);
            }
        }

        if (activityAddRequest.getActivityStartTime() > activityAddRequest.getActivityEndTime()) {
            // ERR_100004("活动开始时间不能大于活动结束时间")
            throw new PromoException(PromoMessageEnum.ERR_430004);
        }

        if (activityAddRequest.getActivityObjectTypeList().contains(ActivityObjectTypeEnum.EMPLOYEE.getKey())) {
            if (activityAddRequest.getActivityObjectTypeCascade() == null) {
                // ERR_100005("活动对象类型为员工时，级联选项不能为空"
                throw new PromoException(PromoMessageEnum.ERR_430005);
            }

            if (activityAddRequest.getActivityObjectTypeCascade().equals(ActivityObjectTypeCascadeEnum.ASSIGN_DEPT.getKey())) {
                if (CollectionUtils.isEmpty(activityAddRequest.getObjectIdList())) {
                    // ERR_100006("部门不能为空")
                    throw new PromoException(PromoMessageEnum.ERR_430006);
                }
            }

            if (activityAddRequest.getActivityObjectTypeCascade().equals(ActivityObjectTypeCascadeEnum.ASSIGN_JOB.getKey())) {
                if (CollectionUtils.isEmpty(activityAddRequest.getObjectIdList())) {
                    // ERR_100007("职位不能为空")
                    throw new PromoException(PromoMessageEnum.ERR_430007);
                }
            }
        }

        if (activityAddRequest.getStoreStyle().equals(StoreStyleEnum.ASSIGN.getKey())) {
            if (CollectionUtils.isEmpty(activityAddRequest.getStoreIdList())) {
                // ERR_100008("指定档口不能为空")
                throw new PromoException(PromoMessageEnum.ERR_430008);
            }
        }
    }

    @Resource
    private ApplicationContext applicationContext;
    private List<Predicate<ActivityWrapper>> predicates;

    private Map<Byte, Function<ActivityWrapper, DiscountFun>> discountMap;

    @Override
    public void afterPropertiesSet() {
        Map<String, ActivityDiscountPredicate> map = applicationContext.getBeansOfType(ActivityDiscountPredicate.class);
        predicates = new ArrayList<>(map.size());
        predicates.addAll(map.values());


        Map<String, ActivityDiscountFunction> dMap = applicationContext.getBeansOfType(ActivityDiscountFunction.class);
        discountMap = new HashMap<>(dMap.size());

        dMap.forEach((key, value) ->
                discountMap.put(value.getDiscountType(), value)
        );
    }


}

